import logging


class ArrayDeque:
    def __init__(self, capacity: int):
        """构造方法"""
        self.__nums = [0] * capacity
        self.__front = 0
        self.__size = 0

    def size(self):
        """获取双向队列的长度"""
        return self.__size

    def capacity(self):
        """获取双向队列的容量"""
        return len(self.__nums)

    def is_empty(self):
        """判断双向队列是否为空"""
        return self.__size == 0

    def index(self, i: int) -> int:
        """计算环形数组索引"""
        # 通过取余操作实现数组首尾相连
        # 当 i 越过数组尾部后，回到头部
        # 当 i 越过数组头部后，回到尾部
        return (i + self.capacity()) % self.capacity()

    def push_first(self, num: int):
        """队首入队"""
        if self.__size == self.capacity():
            logging.warning("双向队列已满")
            return
        # 队首指针向左移动一位
        # 通过取余操作，实现 front 越过数组头部后回到尾部
        self.__front = self.index(self.__front - 1)
        # 将 num 添加至队首
        self.__nums[self.__front] = num
        self.__size += 1
    
    def push_last(self, num: int):
        """队尾入队"""
        if self.__size == self.capacity():
            logging.warning("双向队列已满")
            return
        # 计算尾指针，指向队尾索引 + 1
        rear = self.index(self.__front + self.__size)
        # 将 num 添加至队尾
        self.__nums[rear] = num
        self.__size += 1

    def pop_first(self):
        """队首出队"""
        num = self.peek_first()
        # 队首指针向后移动一位
        self.__front = self.index(self.__front + 1)
        self.__size -= 1
        return num

    def pop_last(self):
        """队尾出队"""
        num = self.peek_last()
        self.__size -= 1
        return num

    def peek_first(self):
        """访问队首元素"""
        if self.is_empty():
            raise IndexError("双向队列为空")
        return self.__nums[self.__front]
    
    def peek_last(self):
        """访问队尾元素"""
        if self.is_empty():
            raise IndexError("双向队列为空")
        # 计算尾元素索引，即队首指针 + 队尾元素在数组中的索引
        last = self.index(self.__front + self.__size - 1)
        return self.__nums[last]

    def to_list(self):
        """返回列表用于打印"""
        # 仅转换有效长度范围内的列表元素
        res = []
        for i in range(self.__size):
            j = self.index(self.__front + i)
            res.append(self.__nums[j])
        return res


if __name__ == "__main__":
    # 初始化双向队列
    deque = ArrayDeque(10)
    deque.push_first(3)
